home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Utilities / SEUtils.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  12.1 KB  |  445 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        SEUtils.cpp
  3.  
  4.     Contains:    Semantic Event Utility Functions implementation.
  5.  
  6.     Owned by:    Nick Pilch
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     
  11.         
  12. */
  13.  
  14. #ifndef __ERRORS__
  15. #include <Errors.h>
  16. #endif
  17.  
  18. #ifndef _ODDESUTL_
  19. #include <ODDesUtl.h>
  20. #endif
  21.  
  22. #ifndef SOM_ODAppleEvent_xh
  23. #include "ODAplEvt.xh"
  24. #endif
  25.  
  26. #ifndef SOM_ODOSLToken_xh
  27. #include "ODOSLTkn.xh"
  28. #endif
  29.  
  30. #ifndef SOM_ODNameResolver_xh
  31. #include "NamRslvr.xh"
  32. #endif
  33.  
  34. #ifndef __FILES__
  35. #include <Files.h>
  36. #endif
  37.  
  38. #ifndef _EXCEPT_
  39. #include "Except.h"
  40. #endif
  41.  
  42. #ifndef _ODMEMORY_
  43. #include "ODMemory.h"
  44. #endif
  45.  
  46. #ifndef __STRING__
  47. #include <string.h>
  48. #endif
  49.  
  50. #ifndef __STDLIB__
  51. #include <stdlib.h>
  52. #endif
  53.  
  54. #ifndef __QUICKDRAW__
  55. #include <Quickdraw.h>
  56. #endif
  57.  
  58. #ifndef __AEOBJECTS__
  59. #include <AEObjects.h>
  60. #endif
  61.  
  62. #pragma segment ODSEUtils
  63.  
  64. #ifndef _SEUTILS_
  65. #include "SEUtils.h"
  66. #endif
  67.  
  68. #ifndef _SIHLPABS_
  69. #include "SIHlpAbs.h"
  70. #endif
  71.  
  72. #ifndef _TEMPITER_
  73. #include "TempIter.h"
  74. #endif
  75.  
  76. #ifndef SOM_ODEmbeddedFramesIterator_xh
  77. #include "EmbFrItr.xh"
  78. #endif
  79.  
  80. #ifndef _ODUTILS_
  81. #include <ODUtils.h>
  82. #endif
  83.  
  84. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  85. #include <StdDefs.xh>
  86. #endif
  87.  
  88.  
  89. OSErr MyAECoerceDescPtr(AEDesc theAEDesc, DescType toType, Ptr dataPtr,
  90.                         Size maximumSize, Size* actualSize);
  91. long MyRandom(long count);
  92.  
  93. ODBoolean MissingParams(const AppleEvent* message)
  94. {
  95.     AEKeyword     missedKeyword;
  96.     DescType    ignoreType;
  97.     Size        ignoreSize;
  98.     OSErr         myErr;
  99.     
  100.     myErr = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  101.                                 &ignoreType, (Ptr)&missedKeyword,
  102.                                 sizeof(missedKeyword), &ignoreSize);
  103.     return myErr == noErr;
  104. }
  105.  
  106. /* -- I've made this a memeber function of ODApplicatiin (in Shell.cp)
  107. // HEY! This function assumes that typeCode is typeChar and toType is typeFSS.
  108. //pascal OSErr Pathname2FSSpec(DescType        typeCode,
  109. //                                Ptr            dataPtr,
  110. //                                Size        dataSize,
  111. //                                DescType    toType,
  112. //                                long        handlerRefCon,
  113. //                                AEDesc*        result)
  114.  
  115.  
  116. // ODDescCoercionHandler 
  117. void Pathname2FSSpec(    ODPart* thePart, DescType typeCode, Ptr dataPtr,
  118.                         Size dataSize, DescType    toType, long handlerRefCon,
  119.                         AEDesc*     result)
  120. {
  121.     Str255        fileName;
  122.     FSSpec        fileSpec;
  123.     const short    kNoVRefNum = 0;
  124.     const long    kNoDirID = 0;
  125.     OSErr        error;
  126.     
  127.     if (dataSize > sizeof(Str255))
  128.         return bdNamErr;
  129.  
  130.     ODBlockMove(dataPtr, fileName + 1, dataSize);
  131.     fileName[0] = (unsigned char)dataSize;
  132.  
  133.     error = FSMakeFSSpec(kNoVRefNum, kNoDirID, fileName, &fileSpec);
  134.     THROW_IF_ERROR( error );
  135.     
  136.     error = AECreateDesc(typeFSS, (Ptr) &fileSpec, sizeof(fileSpec), result);
  137.     THROW_IF_ERROR( error );
  138. }
  139.  
  140. */
  141.  
  142. /*
  143. The following functions were lifted from Quill.p and translated
  144. */
  145.  
  146. #define genericErr (-1799)
  147. #define errAEBadData (-15310)
  148. Size gActSize;
  149.  
  150.  
  151. OSErr DecodeOrdinal(AEDesc ordData, long count, long* index,
  152.                     Boolean* allFlag, Boolean* zeroFlag)
  153. /* this routine is used whenever an element is specified by an absolute position
  154.   within a sequence of elements - such as "word 3 of window 'johnson'", "any line
  155.   of item 17 of window 'Kelvin'", etc.  The data specifying the position can be
  156.   a positive integer (which just means the actual position of the element in the
  157.   sequence: 1 for the first element, 2 for the second, etc.), a negative integer
  158.   (which indicates position relative to the last element of the sequence: -1 is
  159.   the last element, -2 the next to last, etc.), or a descriptor of typeAbsoluteOrdinal:
  160.   kAEFirst, kAELast, kAEMiddle, kAEAny, or kAEAll.  
  161.   
  162.   DecodeOrdinal takes the data specifying the position, and a count of all the elements
  163.   in the sequence under consideration, and returns (whenever possible) a positive integer
  164.   (in the return VAR index) representing the actual position of the element in the sequence 
  165.   (1 for first, 2 for second, etc.).  It also returns flags indicating (a) whether the 
  166.   ordinal was kAEAll and (b) whether the count was 0; both of these are conditions that 
  167.   many calling routines will have to special-case.  In the case of kAEAll, the return VAR 
  168.   index is set to the count; in the case of count = 0, the return VAR index is set to 0.
  169.   
  170.   There are a few error conditions:  (a) count < 0; (b) bad ordData (not an integer, and
  171.   not one of the five defined absolute ordinal specifiers).  **CHECK - should "integer ordData
  172.   out of range" (for example, an integer > count, or < -count, or = 0) be an error,
  173.   or should we allow that so that people can talk about "the hypothetical element
  174.   beyond the last", or whatever?  For now, let's make that a non-error.
  175.   
  176.   INPUTS:    ordData        a descriptor that specifies an ordinal - either
  177.                           an integer (positive or negative) or something
  178.                         of typeAbsoluteOrdinal
  179.             count        the total number of elements in the group involved
  180.                         (number of windows, number or chars, or whatever)
  181.             index        return VAR for the actual position being described
  182.             allFlag        return VAR: TRUE if the ordData was kAEAll, FALSE o.w.
  183.             zeroFlag    return VAR: TRUE if the count was zero (for many
  184.                         calling routines this is an error condition), FALSE o.w.
  185.   OUTPUTS:    error code (noErr if none)
  186. */
  187. {
  188.     OSErr myErr;
  189.     DescType absOrd;
  190.     long intOrd;
  191.  
  192.   myErr = genericErr;
  193.   *index = count;
  194.   *allFlag = kODFalse;
  195.   
  196.   *zeroFlag = (count == 0);
  197.   if (count < 0)
  198.   {
  199.       myErr = errAEBadData;
  200.       goto exit;
  201.     }
  202.   
  203.   myErr = MyAECoerceDescPtr(ordData, typeAbsoluteOrdinal, (Ptr)&absOrd,
  204.                               sizeof(absOrd), &gActSize);
  205.   if (myErr == noErr)
  206.     {
  207.       /* got an absolute ordinal */
  208.       /* note that, as we enter here, index == count and myErr == noErr */
  209.       *allFlag = (absOrd == kAEAll);
  210.       if (*allFlag)
  211.           goto exit;    /* finish up */
  212.         
  213.       if ((absOrd != kAEFirst) && (absOrd != kAELast)
  214.               && (absOrd != kAEMiddle) && (absOrd != kAEAny))
  215.         {
  216.           myErr = errAEBadData;
  217.           goto exit;
  218.         }
  219.         
  220.       if (*zeroFlag || (absOrd == kAELast))
  221.           goto exit; /* in both cases, index == count (already done) */
  222.         
  223.       if (absOrd == kAEFirst)
  224.           *index = 1;
  225.       else if (absOrd == kAEMiddle)
  226.           *index = (count + 1) / 2;
  227.       else
  228.           *index = MyRandom(count);
  229.       
  230.       goto exit;
  231.     }    /* of absolute ordinal */
  232.     
  233.   /* try actual integer */
  234.   myErr = MyAECoerceDescPtr(ordData, typeLongInteger, (Ptr)&intOrd,
  235.                                   sizeof(intOrd), &gActSize);
  236.   if (myErr)
  237.     goto exit;
  238.       
  239.   if (intOrd < 0)
  240.       *index = count + intOrd + 1;    /* e.g., intOrd == -1 means index == count */
  241.   else
  242.       *index = intOrd;
  243.   
  244.   /* should we validate index here (wrt count)?  let's skip it for now */
  245.   
  246. exit:    /* finish up */
  247.   return myErr;
  248. }
  249.  
  250. OSErr MyAECoerceDescPtr(AEDesc theAEDesc, DescType toType, Ptr dataPtr,
  251.                         Size maximumSize, Size* actualSize)
  252. /* this routine plugs a hole that's been nagging at me in the AppleEvents
  253.   interface.  It takes a descriptor and coerces it to a desired type; but
  254.   instead of returning a descriptor, it returns data in a buffer specified
  255.   by the caller.
  256.   INPUTS:    theAEDesc        descriptor to be coerced
  257.               toType            type to coerce it to
  258.             dataPtr            ptr to data buffer
  259.             maximumSize        maximum length in bytes of data to be returned
  260.             actualSize        actual length in bytes of data for the descriptor
  261.   OUTPUTS:    error code (noErr if none)
  262.   ERRORS:
  263.   SIDE EFFECTS:
  264.   NOTES:    12/16/91    BHM        (1) Changed to avoid unecessary duplication when the type
  265.                                   doesn't really change (this should also enable it to handle
  266.                                 typeWildCard better)
  267.                                 (2) We don't need to dispose of newDesc because it is a direct
  268.                                 copy (not a duplicate) of either theAEDesc or resultDesc - that
  269.                                 is, it contains the same handle
  270.             03/12/92    BHM        Added special case to deal with NIL data handles (which should only 
  271.                                 occur for typeNull, I believe)
  272. */
  273. {
  274.     short myErr;
  275.     AEDesc newDesc;
  276.     AEDesc resultDesc = NULL_DESCRIPTOR_DEFINITION;
  277.     Size transferSize;
  278.  
  279.   myErr = errAECoercionFail;
  280.   
  281.   /* to avoid unnecessary duplication, check old type vs. new type */
  282.   if ((theAEDesc.descriptorType == toType) || (toType == typeWildCard))
  283.       newDesc = theAEDesc;
  284.   else
  285.     {
  286.       /* must coerce to new type */
  287.       myErr = AECoerceDesc(&theAEDesc, toType, &resultDesc); 
  288.       if (myErr)
  289.           goto exit;
  290.       newDesc = resultDesc;
  291.     }
  292.         
  293. //  WITH newDesc DO
  294.     {
  295.       /* special-case for NIL handle */    /* should I **CHECK to make sure it's typeNull here? */
  296.       if (newDesc.dataHandle == kODNULL)
  297.         {
  298.           actualSize = 0;
  299.           myErr = noErr;
  300.           goto exit;
  301.         }
  302.         
  303.       /* not NIL handle - get the size */
  304.       *actualSize = ODGetHandleSize((ODHandle)newDesc.dataHandle);
  305.         myErr = MemError();
  306.         if (myErr)
  307.               goto exit;
  308.     
  309.       /* calculate number of bytes to move */
  310.       transferSize = *actualSize;
  311.       if (maximumSize < transferSize)
  312.           transferSize = maximumSize;
  313.     
  314.       /* move the data */
  315. //      HLock(newDesc.dataHandle);
  316.       ODBlockMove(*(newDesc.dataHandle), dataPtr, transferSize);
  317. //      HUnlock(newDesc.dataHandle);
  318.     }    /* of WITH newDesc */
  319.     
  320.   /* everything fine */
  321.   myErr = noErr;
  322.     
  323. exit:    /* finish up */
  324.   AEDisposeDesc(&resultDesc);
  325.   return myErr;
  326. }    /* MyAECoerceDescPtr */
  327.  
  328. long MyRandom(long count)
  329. /* return a random integer between 1 and count, inclusive
  330.   INPUTS:    count        upper bound for random number
  331.   OUTPUTS:    a random integer between 1 and count, inclusive
  332.   NOTES:    **CHECK - this is a quick, dirty, and WRONG version
  333.               to be used for testing only
  334. */
  335. {
  336. long longRandom;
  337.  
  338.   longRandom = 0x10000*Random() + Random();
  339.   return (labs(longRandom) % count) + 1;
  340. }    /* MyRandom */
  341.  
  342. //------------------------------------------------------------------------------
  343. // GetSLongAttr
  344. //------------------------------------------------------------------------------
  345.  
  346. ODSLong GetSLongAttr(AppleEvent* ae, AEKeyword keyword)
  347. {
  348.     OSErr        result;
  349.     ODSLong    value;
  350.     DescType    actualType;
  351.     Size        sizeOfBuffer = sizeof(value);
  352.     Size        actualSize;
  353.  
  354.     result = AEGetAttributePtr(ae, keyword, typeWildCard, &actualType,
  355.                                     (Ptr)&value, sizeOfBuffer, &actualSize);
  356.     if (result != noErr)
  357.         THROW((ODError)result);
  358.     //if ((actualType != typeShortInteger) || (actualSize != sizeOfBuffer))
  359.     if (actualSize != sizeOfBuffer)
  360.         THROW(kODErrOutOfMemory);
  361.         
  362.     return value;
  363. }
  364.  
  365. //------------------------------------------------------------------------------
  366. // GetSLongAttrOD
  367. //------------------------------------------------------------------------------
  368.  
  369. ODSLong GetSLongAttrOD(ODAppleEvent* ae, AEKeyword keyword)
  370. {
  371.     AppleEvent realAE;
  372.     THROW_IF_ERROR( ODDescToAEDesc( ae, &realAE ) ) ;
  373.     ODSLong result = GetSLongAttr( &realAE, keyword );
  374.     (void)AEDisposeDesc( &realAE );
  375.     return result;
  376. }
  377.  
  378. //------------------------------------------------------------------------------
  379. // ThrowIfCantCoerce
  380. //------------------------------------------------------------------------------
  381.  
  382. // does an in-place coercion!
  383. void ThrowIfCantCoerce( AEDesc* data, DescType desiredType )
  384. {
  385.     if ( data->descriptorType == desiredType )
  386.         return ;
  387.  
  388.     AEDesc newDesc ;
  389.     THROW_IF_ERROR( AECoerceDesc( data, desiredType, &newDesc ) ) ;
  390.     AEDisposeDesc( data ) ;
  391.     *data = newDesc ;
  392. }
  393.  
  394. //------------------------------------------------------------------------------
  395. // ThrowIfNotAbsent
  396. //------------------------------------------------------------------------------
  397.  
  398. void ThrowIfNotAbsent( OSErr err )
  399. {
  400.     if ( (err == noErr) || ( err == errAEDescNotFound ) )
  401.         return ;
  402.     THROW( err ) ;
  403. }
  404.  
  405. //------------------------------------------------------------------------------
  406. // UpdateUserToken
  407. //------------------------------------------------------------------------------
  408.  
  409. void UpdateUserToken(Environment* ev, ODNameResolver* resolver,
  410.                         ODOSLToken* odToken, AEDesc* desc)
  411. {
  412.     ODDesc*    userODToken = resolver->GetUserToken(ev, odToken);
  413.     THROW_IF_ERROR(AEDescToODDesc(desc, userODToken));
  414.     THROW_IF_ERROR(AEDisposeDesc(desc));
  415. }
  416.  
  417. //------------------------------------------------------------------------------
  418. // CountEmbeddedParts
  419. //------------------------------------------------------------------------------
  420.  
  421. ODSLong CountEmbeddedParts(Environment* ev, ODPart* prt)
  422. {
  423.     if ( prt == kODAppShell ) return 1;
  424.  
  425.     ODSLong result = 0;
  426.     for ( TempODEmbeddedFramesIterator iter(ev,prt,kODNULL);
  427.             iter.Current(); iter.Next() )
  428.     {
  429.         ++result;
  430.     }
  431.     return result;
  432. }
  433.  
  434. //------------------------------------------------------------------------------
  435. // ODDisposeAppleEvent
  436. //------------------------------------------------------------------------------
  437.  
  438. OSErr ODDisposeAppleEvent( AppleEvent* aevt )
  439. {
  440.     (void)AEDisposeDesc( aevt );
  441.     return AEDisposeDesc( aevt );
  442. }
  443.  
  444.  
  445.